package cn.findviewbydream.evil.app.service.impl;

import cn.findviewbydream.evil.app.dao.OrderDAO;
import cn.findviewbydream.evil.app.enums.OrderItemStateType;
import cn.findviewbydream.evil.app.exception.DeleteOrderItemException;
import cn.findviewbydream.evil.app.exception.UpdateOrderException;
import cn.findviewbydream.evil.app.exception.UpdateOrderItemException;
import cn.findviewbydream.evil.app.service.OrderService;
import cn.findviewbydream.evil.app.websocket.WebSocketHandlerImpl;
import cn.findviewbydream.evil.main.entity.BaseSeatEntity;
import cn.findviewbydream.evil.main.entity.OrderEntity;
import cn.findviewbydream.evil.main.entity.OrderItemEntity;
import cn.findviewbydream.evil.mealorderofwaiter.enums.SocketEventType;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/********************************************
 * 工程名：MealOrder
 * 包名：cn.findviewbydream.evil.app.service.impl
 * 时间：17-1-20
 * 作者：白雨濃 evil
 * 邮箱：evilbai@foxmail.com
 * 内容：
 ********************************************/
@Service
public class OrderServiceImpl implements OrderService
{
    private Logger logger = LoggerFactory.getLogger(OrderService.class);

    private final OrderDAO orderDAO;

    @Autowired
    public OrderServiceImpl(OrderDAO orderDAO) {this.orderDAO = orderDAO;}

    /**
     * @return 座位列表
     */
    @Override
    public List<BaseSeatEntity> getSeatList()
    {
        return orderDAO.selectSeatList();
    }

    /**
     * @return 未完成的订单列表
     */
    @Override
    public List<OrderEntity> getUnFinishOrderList()
    {
        return orderDAO.selectUnFinishOrderList();
    }

    /**
     * 完成的订单列表
     *
     * @param start 开始时间
     * @param end   结束时间->允许为空
     * @return 完成的订单列表
     */
    //TODO:未完成
    @Override
    public List<OrderEntity> getFinishOrderList(@NotNull Date start, Date end)
    {
        return null;
    }

    /**
     * 获得订单项目列表通过订单id
     *
     * @param orderId 订单id
     * @return 订单项目列表
     */
    @Override
    public List<OrderItemEntity> getOrderItemListByOrderId(int orderId)
    {
        return orderDAO.selectOrderItemListByOrderId(orderId);
    }

    /**
     * 修改订单项目中菜的数量
     * 如果菜单数量>0 update数据 meal_num by order_item_id
     *
     * @param json List<OrderItemEntity> json
     * @return 是否成功
     */
    @Override
    @Transactional
    public Boolean setOrderItemListNum(int orderId, @NotNull String json) throws RuntimeException
    {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        List<OrderItemEntity> list = gson.fromJson(json, new TypeToken<List<OrderItemEntity>>() {}.getType());

        for (OrderItemEntity entity : list)
        {
            if (entity.getMealNum() == 0)
            {
                try
                {
                    orderDAO.deleteOrderItem(entity.getOrderItemId());
                }
                catch (Exception e)
                {
                    logger.error(e.toString());
                    throw new DeleteOrderItemException(e.getMessage());
                }
            }
            else
            {
                try
                {
                    if (entity.getMealId() == null)
                        throw new UpdateOrderItemException("菜单项目空值");

                    orderDAO.updateOrderItemMealNum(entity.getOrderItemId(), entity.getMealNum(), entity
                            .getMealNum() * entity.getMealId().getPrice());
                }
                catch (Exception e)
                {
                    logger.error(e.toString());
                    throw new UpdateOrderItemException(e.getMessage());
                }
            }
        }

        /*全部订单项目更新完成后,更新订单表中的总钱数*/
        boolean isSuccess = setOrderTotalUpdate(orderId);
        if (!isSuccess)
            throw new UpdateOrderItemException("订单总数更新出错");

        /*发送Socket 带着订单id*/
        WebSocketHandlerImpl.Companion.sendMessageToUsers("RE|" + orderId);
        /*成功插入后->发送Socket 状态102 刷新订单列表*/
        WebSocketHandlerImpl.Companion.sendMessageToUsers(SocketEventType.ORDERLIST.getIndex());

        return true;
    }

    /**
     * 更新订单中的总钱数
     *
     * @param orderId id
     * @return 是否成功
     */
    @NotNull
    @Override
    public Boolean setOrderTotalUpdate(int orderId)
    {
        List<OrderItemEntity> list = orderDAO.selectOrderItemListByOrderId(orderId);
        int sum = 0;
        /*查询该订单id下的所有项目,获得total加和*/
        for (OrderItemEntity entity : list)
            sum += entity.getMealTotal();
        try
        {
            return orderDAO.updateOrderTotal(orderId, sum) == 1;
        }
        catch (Exception e)
        {
            throw new UpdateOrderException("更新订单总金额错误");
        }
    }

    @Override
    @Transactional
    public Boolean setOrderItemDelete(int orderId)
    {
        List<OrderItemEntity> list = orderDAO.selectOrderItemListByOrderId(orderId);
        for (OrderItemEntity itemEntity : list)
            /*如果有菜品正在处于 制作||上菜||待结算 状态，禁止删除订单*/
            if (itemEntity.getState() == OrderItemStateType.MAKING ||
                    itemEntity.getState() == OrderItemStateType.COMPLETE_MAKE ||
                    itemEntity.getState() == OrderItemStateType.UNLIQUIDATED)
                throw new UpdateOrderException("该订单禁止失效，订单中包含正在进行的项目！");

        /*如果没有活动项目，将订单的active 为false remark 为失效 订单下项目全部list 删除*/

        OrderEntity entity = orderDAO.selectOrderByOrderId(orderId);
        entity.setActive(false);
        entity.setRemark("失效");

        /*删除订单项目列表*/
        for (OrderItemEntity itemEntity : list)
            if (orderDAO.deleteOrderItem(itemEntity.getOrderItemId()) != 1)
                throw new DeleteOrderItemException("删除订单列表失败！");

        /*更新订单为失效状态*/
        if (orderDAO.updateOrderEntity(entity) != 1)
            throw new UpdateOrderException("更新订单为失效失败！");

        /*成功更新后->发送Socket 状态102 刷新订单列表*/
        WebSocketHandlerImpl.Companion.sendMessageToUsers(SocketEventType.ORDERLIST.getIndex());
        return true;
    }

    @Override
    @Transactional
    public Boolean setFinishOrder(@NotNull String json)
    {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        OrderEntity entity = gson.fromJson(json, new TypeToken<OrderEntity>() {}.getType());
        if (entity == null)
            throw new UpdateOrderException("空订单错误，请重试！");

        /*订单失活*/
        entity.setActive(false);

        /*订单项目失活*/
        List<OrderItemEntity> itemList = orderDAO.selectOrderItemListByOrderId(entity.getOrderId());
        for (OrderItemEntity orderItemEntity : itemList)
        {
            if (orderDAO.updateOrderItemState(orderItemEntity.getOrderItemId()
                    , OrderItemStateType.OVERDUE) != 1)
                throw new UpdateOrderException("更新订单项目错误，请重试！");
        }

        if (orderDAO.updateOrderEntity(entity) != 1)
            throw new UpdateOrderException("发生错误，请重试！");

        /*成功更新后->发送Socket 状态102 刷新订单列表*/
        WebSocketHandlerImpl.Companion.sendMessageToUsers(SocketEventType.ORDERLIST.getIndex());

        /*成功更新后->发送Socket 状态101 刷新座位列表*/
        WebSocketHandlerImpl.Companion.sendMessageToUsers(SocketEventType.SEATLIST.getIndex());

        return true;
    }
}
